/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * This file is part of JMail                                              *
 * Copyright (C) 2002-2003 Yvan Norsa <norsay@wanadoo.fr>                  *
 *                                                                         *
 * JMail is free software; you can redistribute it and/or modify           *
 * it under the terms of the GNU General Public License as published by    *
 * the Free Software Foundation; either version 2 of the License, or       *
 * any later version.                                                      *
 *                                                                         *
 * JMail is distributed in the hope that it will be useful,                *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 * GNU General Public License for more details.                            *
 *                                                                         *
 * You should have received a copy of the GNU General Public License along *
 * with JMail; if not, write to the Free Software Foundation, Inc.,        *
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                 *
 *                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.mail.*;
import javax.swing.*;
import javax.swing.UIManager.*;

/** Main window */
final class JMailWindow extends JFrame {
	private Locale locale;

	/** Language resource */
	private ResourceBundle msgBundle;

	private JMenuBar menuBar;

	/** "File" menu */
	private JMenu fileMenu;

	/** "New" sub-menu */
	private JMenu newMenu;

	/** "Mail" menu item */
	private JMenuItem newMsgMenuItem;

	/** "Folder" menu item */
	private JMenuItem newFolderMenuItem;

	/** "Open..." menu item */
	private JMenuItem openMenuItem;

	private JMenuItem saveMenuItem;

	private JMenu folderMenu;
	private JMenuItem folderNewMenuItem;
	private JMenuItem folderDeleteMenuItem;

	private JMenuItem printMenuItem;

	private JMenuItem selectMenuItem;

	/** "Exit" menu item */
	private JMenuItem exitMenuItem;

	/** "Edit" menu */
	private JMenu editMenu;

	/** "Move in folder..." menu item */
	private JMenuItem moveMenuItem;

	/** "Copy in folder..." menu item */
	private JMenuItem copyMenuItem;

	/** "Delete" menu item */
	private JMenuItem deleteMenuItem;

	private JMenuItem filtersMenuItem;

	private JMenuItem profileMenuItem;

	private JMenuItem ldapMenuItem;
	private JMenuItem addressBookMenuItem;

	/** "Mail" menu */
	private JMenu messageMenu;

	/** "New mail" menu item */
	private JMenuItem newMsgMenuItem2;

	/** "Reply..." menu item */
	private JMenuItem replyMenuItem;

	/** "Reply all..." menu item */
	private JMenuItem replyallMenuItem;

	/** "Forward..." menu item */
	private JMenuItem forwardMenuItem;

	/** "Look & Feel" menu */
	private JMenu lafMenu;

	private ButtonGroup bGroup;
	private LookAndFeelInfo lafInfos[];
	private JRadioButtonMenuItem lafButtons[];

	private ButtonGroup languageBGroup;

	private JMenu languageMenu;
	private JRadioButtonMenuItem englishMenuItem;
	private JRadioButtonMenuItem frenchMenuItem;
	private JRadioButtonMenuItem espanolMenuItem;

	private MainPanel panel;

	/** User profile */
	private Profile profile;

	private JMailWindowListener listener;

	private String currentLaf;

	private boolean profileHasChanged;

	/**
	 * Constructor
	 * 
	 * @param locale
	 *            locale used
	 */
	protected JMailWindow(Locale locale) {
		super("JMail " + Common.JMAIL_VERSION);

		profileHasChanged = false;

		this.locale = locale;
		msgBundle = ResourceBundle.getBundle("MsgBundle", this.locale);

		init();

		try {
			String crossPlatformLookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();

			currentLaf = crossPlatformLookAndFeel;

			for (int i = 0; i < lafInfos.length; i++) {
				if (lafInfos[i].getClassName().compareTo(crossPlatformLookAndFeel) == 0) {
					lafButtons[i].setSelected(true);
					break;
				}
			}

			/** Set on the *universal* L&F */

			changeLaf(crossPlatformLookAndFeel);
		}

		catch (Exception e) {
			e.printStackTrace();
		}

		selectProfile();

		if (profile.getType().compareTo("pop3") == 0)
			setFolderMenuItemsEnabled(false);

		setPanel();

		addWindowListener(listener);

		setSize(800, 600);

		setVisible(true);

		if (profile.getType().compareTo("pop3") != 0) {
			FolderListener f = new FolderListener(panel);
			f.start();
		}
	}

	/** Initialisation of menus */
	private void init() {
		listener = new JMailWindowListener();

		/** Init menus */
		menuBar = new JMenuBar();

		fileMenu = new JMenu(msgBundle.getString("JMailWindow.fileMenuLabel"));
		fileMenu.setMnemonic('F');

		newMenu = new JMenu(msgBundle.getString("JMailWindow.newMenuLabel"));
		newMenu.setMnemonic('N');
		fileMenu.add(newMenu);

		newMsgMenuItem = newMenu.add(msgBundle.getString("JMailWindow.newMsgMenuItemLabel"));
		newMsgMenuItem.setAccelerator(KeyStroke.getKeyStroke('N', Event.CTRL_MASK));
		newMsgMenuItem.addActionListener(listener);

		newMenu.addSeparator();

		newFolderMenuItem = newMenu.add(msgBundle.getString("JMailWindow.newFolderMenuItemLabel"));
		newFolderMenuItem.setMnemonic('R');
		newFolderMenuItem.addActionListener(listener);

		openMenuItem = fileMenu.add(msgBundle.getString("JMailWindow.openMenuItemLabel"));
		openMenuItem.setAccelerator(KeyStroke.getKeyStroke('O', Event.CTRL_MASK));
		openMenuItem.setMnemonic('O');
		openMenuItem.setEnabled(false);
		openMenuItem.addActionListener(listener);

		saveMenuItem = fileMenu.add(msgBundle.getString("JMailWindow.saveMenuItemLabel"));
		saveMenuItem.setAccelerator(KeyStroke.getKeyStroke('S', Event.CTRL_MASK));
		saveMenuItem.setMnemonic('E');
		saveMenuItem.setEnabled(false);
		saveMenuItem.addActionListener(listener);

		fileMenu.addSeparator();

		folderMenu = new JMenu(msgBundle.getString("JMailWindow.folderMenuLabel"));
		folderMenu.setMnemonic('D');
		fileMenu.add(folderMenu);

		folderNewMenuItem = folderMenu.add(msgBundle.getString("JMailWindow.folderNewMenuItemLabel"));
		folderNewMenuItem.addActionListener(listener);

		folderDeleteMenuItem = folderMenu.add(msgBundle.getString("JMailWindow.folderDeleteMenuItemLabel"));
		folderDeleteMenuItem.setEnabled(false);
		folderDeleteMenuItem.addActionListener(listener);

		fileMenu.addSeparator();

		printMenuItem = fileMenu.add(msgBundle.getString("JMailWindow.printMenuItemLabel"));
		printMenuItem.setAccelerator(KeyStroke.getKeyStroke('P', Event.CTRL_MASK));
		printMenuItem.setMnemonic('I');
		printMenuItem.setEnabled(false);
		printMenuItem.addActionListener(listener);

		fileMenu.addSeparator();

		selectMenuItem = fileMenu.add(msgBundle.getString("JMailWindow.selectMenuItemLabel"));
		selectMenuItem.setMnemonic('S');
		selectMenuItem.addActionListener(listener);

		fileMenu.addSeparator();

		exitMenuItem = fileMenu.add(msgBundle.getString("JMailWindow.exitMenuItemLabel"));
		exitMenuItem.setAccelerator(KeyStroke.getKeyStroke('Q', Event.CTRL_MASK));
		exitMenuItem.setMnemonic('Q');
		exitMenuItem.addActionListener(listener);

		fileMenu = menuBar.add(fileMenu);

		editMenu = new JMenu(msgBundle.getString("JMailWindow.editMenuLabel"));
		editMenu.setMnemonic('E');

		moveMenuItem = editMenu.add(msgBundle.getString("JMailWindow.moveMenuItemLabel"));
		moveMenuItem.setAccelerator(KeyStroke.getKeyStroke('V', Event.CTRL_MASK + Event.SHIFT_MASK));
		moveMenuItem.setMnemonic('D');
		moveMenuItem.setEnabled(false);
		moveMenuItem.addActionListener(listener);

		copyMenuItem = editMenu.add(msgBundle.getString("JMailWindow.copyMenuItemLabel"));
		copyMenuItem.setMnemonic('C');
		copyMenuItem.setEnabled(false);
		copyMenuItem.addActionListener(listener);

		editMenu.addSeparator();

		deleteMenuItem = editMenu.add(msgBundle.getString("JMailWindow.deleteMenuItemLabel"));
		deleteMenuItem.setMnemonic('E');
		deleteMenuItem.setEnabled(false);
		deleteMenuItem.addActionListener(listener);

		editMenu.addSeparator();

		filtersMenuItem = editMenu.add(msgBundle.getString("JMailWindow.filtersMenuItemLabel"));
		filtersMenuItem.setMnemonic('F');
		filtersMenuItem.addActionListener(listener);

		editMenu.addSeparator();

		profileMenuItem = editMenu.add(msgBundle.getString("JMailWindow.profileMenuItemLabel"));
		profileMenuItem.setMnemonic('P');
		profileMenuItem.addActionListener(listener);

		editMenu.addSeparator();

		ldapMenuItem = editMenu.add(msgBundle.getString("JMailWindow.ldapMenuItemLabel"));
		ldapMenuItem.addActionListener(listener);

		addressBookMenuItem = editMenu.add(msgBundle.getString("JMailWindow.addressBookMenuItemLabel"));
		addressBookMenuItem.addActionListener(listener);

		editMenu = menuBar.add(editMenu);

		messageMenu = new JMenu(msgBundle.getString("JMailWindow.messageMenuLabel"));
		messageMenu.setMnemonic('M');

		newMsgMenuItem2 = messageMenu.add(msgBundle.getString("JMailWindow.newMsgMenuItem2Label"));
		newMsgMenuItem2.setAccelerator(KeyStroke.getKeyStroke('N', Event.CTRL_MASK));
		newMsgMenuItem2.setMnemonic('N');
		newMsgMenuItem2.addActionListener(listener);

		messageMenu.addSeparator();

		replyMenuItem = messageMenu.add(msgBundle.getString("JMailWindow.replyMenuItemLabel"));
		replyMenuItem.setAccelerator(KeyStroke.getKeyStroke('R', Event.CTRL_MASK));
		replyMenuItem.setMnemonic('R');
		replyMenuItem.setEnabled(false);
		replyMenuItem.addActionListener(listener);

		replyallMenuItem = messageMenu.add(msgBundle.getString("JMailWindow.replyallMenuItemLabel"));
		replyallMenuItem.setAccelerator(KeyStroke.getKeyStroke('R', Event.CTRL_MASK + Event.SHIFT_MASK));
		replyallMenuItem.setMnemonic('t');
		replyallMenuItem.setEnabled(false);
		replyallMenuItem.addActionListener(listener);

		forwardMenuItem = messageMenu.add(msgBundle.getString("JMailWindow.forwardMenuItemLabel"));
		forwardMenuItem.setAccelerator(KeyStroke.getKeyStroke('F', Event.CTRL_MASK));
		forwardMenuItem.setMnemonic('f');
		forwardMenuItem.setEnabled(false);
		forwardMenuItem.addActionListener(listener);

		messageMenu = menuBar.add(messageMenu);

		/** Dynamic generation for the L&F menu */
		lafMenu = new JMenu("Look & Feel");
		lafMenu.setMnemonic('L');

		bGroup = new ButtonGroup();

		lafInfos = UIManager.getInstalledLookAndFeels();
		lafButtons = new JRadioButtonMenuItem[lafInfos.length];

		for (int i = 0; i < lafInfos.length; i++) {
			lafButtons[i] = new JRadioButtonMenuItem(lafInfos[i].getName());
			lafButtons[i].addActionListener(listener);
			bGroup.add(lafButtons[i]);
			lafMenu.add(lafButtons[i]);
		}

		lafMenu = menuBar.add(lafMenu);

		setJMenuBar(menuBar);

		languageMenu = new JMenu(msgBundle.getString("JMailWindow.languageMenuLabel"));

		languageBGroup = new ButtonGroup();

		englishMenuItem = new JRadioButtonMenuItem("English");
		englishMenuItem.addActionListener(listener);
		languageBGroup.add(englishMenuItem);
		languageMenu.add(englishMenuItem);

		frenchMenuItem = new JRadioButtonMenuItem("Francais");
		frenchMenuItem.addActionListener(listener);
		languageBGroup.add(frenchMenuItem);
		languageMenu.add(frenchMenuItem);

		espanolMenuItem = new JRadioButtonMenuItem("Espanol");
		espanolMenuItem.addActionListener(listener);
		languageBGroup.add(espanolMenuItem);
		languageMenu.add(espanolMenuItem);

		if (locale.getLanguage().compareTo("fr") == 0)
			frenchMenuItem.setSelected(true);

		else if (locale.getLanguage().compareTo("es") == 0)
			espanolMenuItem.setSelected(true);

		else
			// if(locale.getLanguage().compareTo("en") == 0)
			englishMenuItem.setSelected(true);

		languageMenu = menuBar.add(languageMenu);

		tryLafs();

		/*
		 * try { String crossPlatformLookAndFeel =
		 * UIManager.getCrossPlatformLookAndFeelClassName();
		 * 
		 * currentLaf = crossPlatformLookAndFeel;
		 * 
		 * for(int i = 0; i < lafInfos.length; i++) {
		 * if(lafInfos[i].getClassName().compareTo(crossPlatformLookAndFeel) ==
		 * 0) { lafButtons[i].setSelected(true); break; } }
		 */
		/** Set on the *universal* L&F */
		/*
		 * changeLaf(crossPlatformLookAndFeel); }
		 * 
		 * catch(Exception e) { e.printStackTrace(); }
		 */
	}

	/** Try every L&F to see if it is supported */
	private void tryLafs() {
		String lafClassName = null;
		Class laf = null;
		LookAndFeel newLaf = null;
		JRadioButtonMenuItem b = null;

		for (int j = 0; j < lafButtons.length; j++) {
			try {
				lafClassName = lafInfos[j].getClassName();
				laf = Class.forName(lafClassName);
				newLaf = (LookAndFeel) (laf.newInstance());

				if (!newLaf.isSupportedLookAndFeel()) {
					b = lafButtons[j];
					b.setEnabled(false);
				}
			}

			catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Set the current Look & Feel
	 * 
	 * @param laf
	 *            class name to use
	 */
	private void changeLaf(String laf) {
		try {
			UIManager.setLookAndFeel(laf);
			SwingUtilities.updateComponentTreeUI(this);
		}

		catch (UnsupportedLookAndFeelException lafE) {
			JOptionPane.showMessageDialog(this, lafE.getMessage(), "UnsupportedLookAndFeelException", JOptionPane.ERROR_MESSAGE);

			String classname = null;
			JRadioButtonMenuItem b = null;

			for (int i = 0; i < lafInfos.length; i++) {
				classname = lafInfos[i].getClassName();

				if (classname.compareTo(laf) == 0) {
					for (int j = 0; j < lafButtons.length; j++) {
						if (lafButtons[j].getText().compareTo(lafInfos[i].getName()) == 0) {
							b = lafButtons[j];
							b.setEnabled(false);
							b.setSelected(false);

							try {
								for (int k = 0; k < lafInfos.length; k++) {
									if (lafInfos[k].getClassName().compareTo(currentLaf) == 0) {
										lafButtons[k].setSelected(true);
										break;
									}
								}

								/** Set on the *universal* L&F */
								changeLaf(currentLaf);
							}

							catch (Exception exce) {
								exce.printStackTrace();
							}

							break;
						}
					}
				}
			}
		}

		catch (Exception e) {
			e.printStackTrace();
		}

		currentLaf = laf;
	}

	/**
	 * Enable or disable menu items related to a mail
	 * 
	 * @param b
	 *            activate or deactivate
	 */
	protected final void setMenuItemsEnabled(boolean b) {
		openMenuItem.setEnabled(b);
		saveMenuItem.setEnabled(b);
		// moveMenuItem.setEnabled(b);
		// copyMenuItem.setEnabled(b);
		deleteMenuItem.setEnabled(b);
		replyMenuItem.setEnabled(b);
		replyallMenuItem.setEnabled(b);
		forwardMenuItem.setEnabled(b);
	}

	/**
	 * Enable or disable menu items related to folder
	 * 
	 * @param b
	 *            activate or deactivate
	 */
	protected final void setFolderMenuItemsEnabled(boolean b) {
		folderMenu.setEnabled(b);
		newFolderMenuItem.setEnabled(b);
		folderNewMenuItem.setEnabled(b);
		folderDeleteMenuItem.setEnabled(b);
		moveMenuItem.setEnabled(b);
		copyMenuItem.setEnabled(b);
	}

	/** Properly disconnect and exit */
	private void exit() {
		panel.disconnect();

		if (profileHasChanged)
			profile.save();

		System.exit(0);
	}

	/** Shows the user the profile selection dialog */
	private void selectProfile() {
		if (profileHasChanged)
			profile.save();

		profile = null;

		Selection s = new Selection(msgBundle);
		String profileName = null;

		while (profile == null) {
			/** Profile selection */
			while (profileName == null) {
				s.show();
				profileName = s.getChoice();
			}

			s.hide();

			AskPasswordDialog passwordDialog = new AskPasswordDialog(msgBundle.getString("JMailWindow.profilePasswordText"));
			profile = Profile.loadProfile(profileName, passwordDialog.getPassword(), msgBundle);
			passwordDialog.dispose();

			if (profile != null) {
				if (profile.getLdapUser())
					ldapMenuItem.setEnabled(true);

				else
					ldapMenuItem.setEnabled(false);
			}
		}
	}

	/** Updates everything */
	private void update() {
		panel.disconnect();
		setPanel();
		SwingUtilities.updateComponentTreeUI(this);

		if (profile.getLdapUser())
			ldapMenuItem.setEnabled(true);

		else
			ldapMenuItem.setEnabled(false);
	}

	/** Reloads the main panel */
	private void setPanel() {
		panel = new MainPanel(this, profile, msgBundle);
		setContentPane(panel);
	}

	/**
	 * Allows to set the <code>profileHasChanged</code> boolean
	 * 
	 * @param profileHasChanged
	 *            new value of the boolean
	 */
	protected final void setProfileHasChanged(boolean profileHasChanged) {
		this.profileHasChanged = profileHasChanged;
	}

	/** Listener for this class */
	private final class JMailWindowListener extends WindowAdapter implements ActionListener {
		/**
		 * Method called when the windows is closed
		 * 
		 * @param e
		 *            triggered event
		 */
		public final void windowClosing(WindowEvent e) {
			exit();
		}

		/**
		 * This method is invoked when an event is triggered
		 * 
		 * @param e
		 *            event
		 */
		public final void actionPerformed(ActionEvent e) {
			JMenuItem i = (JMenuItem) e.getSource();

			if (i == newMsgMenuItem || i == newMsgMenuItem2) {
				SendMessage sm = new SendMessage(profile, msgBundle);
				sm.dispose();
			}

			else if (i == newFolderMenuItem || i == folderNewMenuItem)
				panel.newFolder();

			else if (i == folderDeleteMenuItem)
				panel.deleteFolder();

			else if (i == openMenuItem) {
				Message currentMessage = panel.getCurrent();

				new ReadMessage(panel.getStore(), panel.getCurrentFolder(), panel, profile, currentMessage, EmailUtils.getMailContent(panel, currentMessage, msgBundle).toString(), msgBundle,
						panel.isAttachmentVisible());
			}

			else if (i == saveMenuItem)

				EmailUtils.saveMessage(panel.getCurrent(), msgBundle);

			else if (i == printMenuItem) {
				/** TODO : do printing stuff */
			}

			else if (i == selectMenuItem) {
				selectProfile();
				update();
			}

			else if (i == exitMenuItem)
				exit();

			else if (i == moveMenuItem)
				panel.moveMsg();

			else if (i == copyMenuItem)
				panel.copyMsg();

			else if (i == deleteMenuItem)
				panel.delete();

			else if (i == filtersMenuItem) {
				EditFilters edit = new EditFilters(panel.getStore(), profile, msgBundle);

				if (edit.hasChanged())
					profileHasChanged = true;

				edit.dispose();
			}

			else if (i == profileMenuItem) {
				EditProfile edit = new EditProfile(profile, msgBundle);

				if (edit.hasChanged()) {
					profileHasChanged = true;

					profile = edit.getModifiedProfile();
					update();
				}

				edit.dispose();
			}

			else if (i == ldapMenuItem) {
				Vector entries = LdapSearch.getList(profile);

				if (entries != null && entries.size() > 0 && profile.getLdapAddresses().size() == 0)
					// profile.getAddresses().addAll(entries);
					profile.getLdapAddresses().addAll(entries);
			}

			else if (i == addressBookMenuItem) {
				ManageAddresses mng = new ManageAddresses(profile, msgBundle);

				if (mng.hasChanged())
					profileHasChanged = true;

				mng.dispose();
			}

			else if (i == replyMenuItem)
				panel.reply();

			else if (i == replyallMenuItem)
				panel.replyall();

			else if (i == forwardMenuItem)
				panel.forward();

			else if (i == englishMenuItem) {
				locale = new Locale("en");
				msgBundle = ResourceBundle.getBundle("MsgBundle", locale);

				init();
				setPanel();
			}

			else if (i == frenchMenuItem) {
				locale = new Locale("fr");
				msgBundle = ResourceBundle.getBundle("MsgBundle", locale);

				init();
				setPanel();
			}

			else if (i == espanolMenuItem) {
				locale = new Locale("es");
				msgBundle = ResourceBundle.getBundle("MsgBundle", locale);

				init();
				setPanel();
			}

			/** L&F button */
			else {
				String name = i.getText();
				String laf = new String();
				JRadioButtonMenuItem b = null;

				/**
				 * TODO : check if there isn't any better way to know which
				 * button has been clicked...
				 */
				for (int j = 0; j < lafButtons.length; j++) {
					if (lafButtons[j].getText().compareTo(name) == 0) {
						b = lafButtons[j];
						laf = lafInfos[j].getClassName();
						break;
					}
				}

				changeLaf(laf);
			}
		}
	}
}
